

package ejb.ebank.managers;



import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;

import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.NoResultException;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;

import ejb.bank.utils.Generator;
import ejb.ebank.entities.Account;
import ejb.ebank.entities.BankCard;
import ejb.ebank.entities.BankClient;



/**
 * Session Bean implementation class AccountMenager
 */
@Stateless
public class AccountMenager implements AccountMenagerRemote {
	
	
	@PersistenceContext(unitName="ebank") 
		private EntityManager manager;
	

	public BankClient changeClientData() {
		// TODO Auto-generated method stub
		return null;
	}

	public void closeAccount() {
		// TODO Auto-generated method stub
		
	}

	
	public Account createAccount(BankClient client, Account account) {
		
		Generator gen = new Generator();
		
		// create acount
		account.setAccountBalance(0);
		String number = this.createAccountNumber(gen);
		account.setAccountNumber(number);
		account.setDebet(0);
		
		// create bank card
		BankCard card = new BankCard();
		card.setCardNumber(number);
		card.setDailyLimit(1000);
		card.setPIN(gen.generatePIN());
		// set card importance (+2 years)
		Calendar calendar = Calendar.getInstance();
		int year = calendar.get(Calendar.YEAR);
		calendar.set(Calendar.YEAR, year + 2);
		Timestamp importance = new Timestamp(calendar.getTimeInMillis());
		card.setImportance(importance);
		
		account.setBankCard(card);
		card.setAccount(account);
		
		// check if client already exist
		ArrayList<Account> accountList = null;
		BankClient bc = this.findClientByPESEL(client.getPesel());
		if(bc != null) {
			account.setBankClient(bc);
			accountList = (ArrayList<Account>) bc.getAccounts();
			accountList.add(account);
			bc.setAccounts(accountList);
			
		} else {
			account.setBankClient(client);
			accountList = new ArrayList<Account>();
			accountList.add(account);
			client.setAccounts(accountList);
		}
		
		this.manager.persist(account);
		
		return account;
	}

	
	
	public List viewAccountHistory(Account account, 
			Timestamp startDate, Timestamp endDate, String type) {

		Query query = this.manager.createQuery("from Operation o" +
				"where o.startDate=:startDate and o.endDate=:endDate" +
				"and o.operationKind.name=:type" +
				"and ");
		
		query.setParameter("startDate", startDate);
		query.setParameter("endDate", endDate);
		query.setParameter("type", type);
		
		
		
		return null;
		
	}

	
	
	public BankClient viewClientData() {
		// TODO Auto-generated method stub
		return null;
	}
	
	
	/**
	 * 
	 * @param pesel
	 * @return BankClient or null if doesn't exist 
	 */
	public BankClient findClientByPESEL(String pesel) {
		
		BankClient client = null;
		try {
			Query query = manager.createQuery("from BankClient bc where bc.pesel=:pesel");
			query.setParameter("pesel", pesel);
			client = (BankClient) query.getSingleResult();
		} catch(NoResultException e) {
			//ignore
		}
		return client;
	}
	
	
	/**
	 * method check if generate account number exist in database
	 * @return account number as String
	 */
	private String createAccountNumber(Generator g) {
		Generator gen = g;
		String number = gen.generateAccountNumber();
		
		while(true) {
			try {
				Query q = manager.createQuery("from Account ac where ac.accountNumber=:number");
				q.setParameter("number", number);
				q.getSingleResult();
				number = gen.generateAccountNumber();
			} catch (NoResultException e) {
				break;
			}
		}
		
		return number;
	}
}
